package com.authine.cloudpivot.ext.controller;

import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.workflow.WorkflowTemplateHeaderModel;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.engine.enums.type.DefaultPropertyType;
import com.authine.cloudpivot.engine.enums.type.ProcessRunMode;
import com.authine.cloudpivot.engine.workflow.model.activity.ParticipantActivity;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.controller.runtime.AbstractFormRuntimeController;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.authine.cloudpivot.web.api.view.runtime.BizObjectVO;
import com.authine.cloudpivot.web.api.view.runtime.FormSaveVO;
import com.authine.cloudpivot.web.api.view.runtime.StartWorkflowDataVO;
import com.authine.cloudpivot.web.api.view.runtime.WorkItemSubmitVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;
import java.util.UUID;

/**
 * 用户自定义发起流程
 */
@RestController
@RequestMapping("/api/cust/form")
@Slf4j
public class CustmStartWorkflow extends AbstractFormRuntimeController {



    @PostMapping("/toStartWorkflow")
    public  ResponseResult toStartWorkflow( String workflowCode,
                                                    String username, Boolean finishStart, String data){


        log.info("请求参数,workflowCode={},username={},finishStart={},data={},",workflowCode,username,finishStart,data);


        StartWorkflowDataVO bizObject = new StartWorkflowDataVO();

        bizObject.setWorkflowCode(workflowCode);
        bizObject.setUsername(username);
        bizObject.setFinishStart(finishStart);
        bizObject.setData(JSON.parseObject(data));


        return startWorkflow(bizObject);

       // return getOkResponseResult("ok");
    }


    @PostMapping("/start_workflow")
    public ResponseResult<String> startWorkflow(@RequestBody StartWorkflowDataVO bizObject) {
        /*
         * { "username": "用户名", "workflowCode": "流程编码", "finishStart": 是否结束发起节点,
         * true/false "data": { "code":"value", "code2":"value2" } }
         */
        if (bizObject == null) {
            return getErrResponseResult("", ErrCode.SYS_PARAMETER_EMPTY.getErrCode(), "参数为空");
        }
        String workflowCode = bizObject.getWorkflowCode();
        String username = bizObject.getUsername();
        boolean finishStart = bizObject.getFinishStart();
        Map<String, Object> data = bizObject.getData();
        log.info("start workflow: workflowCode = {}, username = {}, formData = {}", workflowCode, username,
                JSON.toJSONString(data));

        UserModel userModel = getOrganizationFacade().getUserByUserNameAndCorpId(username, getMainCorpId());
        if (userModel == null){
            userModel = getOrganizationFacade().getUserById(username);
        }
        if (userModel == null) {
            return getErrResponseResult(username, ErrCode.ORG_USER_NONEXISTENT.getErrCode(), "用户不存在");
        }
        WorkflowTemplateHeaderModel headerModel = getAppManagementFacade().getWorkflowTemplateHeader(workflowCode);
        if (headerModel == null) {
            return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程不存在");
        }

        ParticipantActivity participantActivity = getAppManagementFacade().getOriginateActivity(workflowCode, null);
        if (participantActivity == null) {
            return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NO_START_ACTIVITY.getErrCode(), "没有找到流程发起节点");
        }

        BizObjectModel bo = new BizObjectModel(headerModel.getSchemaCode(), data, false);
        bo.setFormCode(participantActivity.getSheetCode());

        String workflowInstanceId;
        if (!finishStart) {
            BizObjectVO bov = new BizObjectVO();
            bov.setBizObject(bo);
            bov.setWorkflowCode(workflowCode);

            if (StringUtils.isBlank(bov.getBizObject().getString(DefaultPropertyType.OWNER_DEPT_ID.getCode()))) {
                bov.getBizObject().setOwnerDeptId(userModel.getDepartmentId());
            }

            FormSaveVO resultVO = saveWorkflow(userModel.getId(), userModel.getId(), bov);
            if (resultVO == null) {
                return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程发起失败1");
            }

            WorkItemModel tempItem = resultVO.getWorkItem();

            if (tempItem == null){
                log.info("tempItem is null .........");
                log.info("resultVO.getWorkflowInstanceId() === {}",resultVO.getWorkflowInstanceId());
                workflowInstanceId = resultVO.getWorkflowInstanceId();
            }else{
                log.info("tempItem is not null .........");
                log.info("resultVO.getWorkflowInstanceId() === {}",resultVO.getWorkflowInstanceId());
                workflowInstanceId = tempItem.getInstanceId();
            }


        } else {
            WorkItemSubmitVO workItemSubmit = new WorkItemSubmitVO();
            workItemSubmit.setBizObject(bo);
            workItemSubmit.setDepatmentId(userModel.getDepartmentId());
            workItemSubmit.setWorkflowCode(workflowCode);
            Map<String, Object> result = submitWorkflowByWorkflowCode(userModel.getId(), userModel.getId(), workItemSubmit);
            if (result == null) {
                return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程发起失败2");
            }

//			Object object = result.get("workItem");
//			if (object == null) {
//				return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程发起失败");
//			}
//			WorkItemModel workItem = (WorkItemModel) object;
//			workflowInstanceId = workItem.getInstanceId();

            if (result.get("workflowInstanceId") instanceof String) {
                workflowInstanceId = result.get("workflowInstanceId").toString();
            } else {
                return getErrResponseResult(workflowCode, ErrCode.WORKFLOW_NOT_EXIST.getErrCode(), "流程发起失败3");
            }

        }
        return getOkResponseResult(workflowInstanceId, "流程发起成功。流程实例id = ".concat(workflowInstanceId));
    }

    /**
     * 保存流程表单
     *
     * @param userId      用户id
     * @param ownerId     拥有者
     * @param bizObjectVO 业务数据对象
     * @return FormSaveVO
     */
    private FormSaveVO saveWorkflow(String userId, String ownerId, BizObjectVO bizObjectVO) {
        String workflowCode = bizObjectVO.getWorkflowCode();

        validateNotEmpty(workflowCode, ErrCode.WORKFLOW_CODE_EMPTY.getErrMsg());
        FormSaveVO formSave = new FormSaveVO();
        BizObjectModel objectModel = bizObjectVO.getBizObject();
        String workflowInstanceId = objectModel.getWorkflowInstanceId();

        //objectModel.setFormCode(getFormCode(workflowInstanceId, workflowCode));
        String objectId = objectModel.getId();

        //是否是发起流程
        boolean isStartWf = StringUtils.isEmpty(workflowInstanceId);

        // 发起流程，防止重复提交
        if (isStartWf) {
            objectModel.setWorkflowInstanceId(UUID.randomUUID().toString().replaceAll("-", ""));
//            this.verifyReplay(bizObjectVO.getReplayToken());
        }

//        if (bizObjectVO.getSaveBizObject()) {
//            if (log.isDebugEnabled()) {
//                log.debug("setSaveBizObject userId = {}, bizObject = {},", userId,
//                        JSONObject.toJSONString(objectModel));
//            }
//            objectId = saveBizObject(userId, objectModel);
//        }
        formSave.setObjectId(objectId);
        WorkItemModel workItem;

        if (!isStartWf) {//暂存
            objectId = temporaryStore(userId, bizObjectVO.getWorkItemId(), objectModel, bizObjectVO.getApproval());
            bizObjectVO.setWorkflowInstanceId(workflowInstanceId);
            workItem = getWorkOrCirculateItem(bizObjectVO.getWorkItemId());
        } else {
            // 发起流程
            String departmentId = objectModel.getString(DefaultPropertyType.OWNER_DEPT_ID.getCode());
            workflowInstanceId = startWorkflow(departmentId, userId, null, objectModel, bizObjectVO.getApproval(), workflowCode, Boolean.FALSE, false, ProcessRunMode.MANUAL);
            workItem = getWorkItemByInstanceIdAndUserId(userId, workflowInstanceId);
            formSave.setWorkflowInstanceId(workflowInstanceId);
        }

        if (workItem != null) {
            if (log.isDebugEnabled()) {
                log.debug("workflowCode = {}, instanceId = {},", workflowCode, workflowInstanceId);
            }

            //saveComment(userId, objectId, objectModel.getSchemaCode(), bizObjectVO.getApproval(), FormActionType.TS);

            formSave.setWorkItem(workItem);

            //BizObjectCreatedModel bizObjectCreated = getBizObjectFacade().getBizObject(userId, objectModel.getSchemaCode(), objectId);
            //writeOperationLogForBizObject(workItem.getInstanceId(), workItem.getId(), workItem.getActivityCode(), OperationType.TEMPORARY_STORAGE, bizObjectCreated);
            //writeOperationLog(workItem.getInstanceId(), workItem.getId(), null, OperationType.TEMPORARY_STORAGE, null);
        }
        return formSave;
    }


}
